<!DOCTYPE html>
<html lang="en">
  <head>
    <title>
        Java-framework-RabbitMQ-1 - rulerLwx Blog
      </title>
        <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui">
    <meta name="renderer" content="webkit">
    <meta http-equiv="Cache-Control" content="no-transform" />
    <meta http-equiv="Cache-Control" content="no-siteapp" />
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="format-detection" content="telephone=no,email=no,adress=no">
    
    <meta name="theme-color" content="#000000" />
    
    <meta http-equiv="window-target" content="_top" />
    
    
    <meta name="description" content="安装RabbitMQ（一） 1、安装Erlang RabbitMQ需要Erlang环境，Erlang([&amp;lsquo;ə:læŋ])是一种通用的" />
    <meta name="generator" content="Hugo 0.73.0 with theme pure" />
    <title>Java-framework-RabbitMQ-1 - rulerLwx Blog</title>
    
    
    <link rel="stylesheet" href="https://rulerLwx.gitee.io/css/style.min.c4bc7071f132c964c2116bca53b392933f377e5ca7b7051ed245187c621a2d3e.css">
    
    <link rel="stylesheet" href="https://cdn.staticfile.org/highlight.js/9.15.10/styles/github.min.css" async>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.4.2/tocbot.css" async>
    <meta property="og:title" content="Java-framework-RabbitMQ-1" />
<meta property="og:description" content="安装RabbitMQ（一） 1、安装Erlang RabbitMQ需要Erlang环境，Erlang([&lsquo;ə:læŋ])是一种通用的" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://rulerLwx.gitee.io/2020/07/java-framework-rabbitmq-1/" />
<meta property="article:published_time" content="2020-07-01T18:58:47+08:00" />
<meta property="article:modified_time" content="2020-07-01T18:58:47+08:00" />
<meta itemprop="name" content="Java-framework-RabbitMQ-1">
<meta itemprop="description" content="安装RabbitMQ（一） 1、安装Erlang RabbitMQ需要Erlang环境，Erlang([&lsquo;ə:læŋ])是一种通用的">
<meta itemprop="datePublished" content="2020-07-01T18:58:47&#43;08:00" />
<meta itemprop="dateModified" content="2020-07-01T18:58:47&#43;08:00" />
<meta itemprop="wordCount" content="4576">



<meta itemprop="keywords" content="" /><meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="Java-framework-RabbitMQ-1"/>
<meta name="twitter:description" content="安装RabbitMQ（一） 1、安装Erlang RabbitMQ需要Erlang环境，Erlang([&lsquo;ə:læŋ])是一种通用的"/>

    <!--[if lte IE 9]>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/classlist/1.1.20170427/classList.min.js"></script>
      <![endif]-->

    <!--[if lt IE 9]>
        <script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
      <![endif]-->
  </head>

  
  

  <body class="main-center theme-black" itemscope itemtype="http://schema.org/WebPage"><header class="header" itemscope itemtype="http://schema.org/WPHeader">
    <div class="slimContent">
      <div class="navbar-header">
        <div class="profile-block text-center">
          <a id="avatar" href="https://gitee.com/rulerLwx" target="_blank">
            <img class="img-circle img-rotate" src="https://rulerLwx.gitee.io/avatar.png" width="200" height="200">
          </a>
          <h2 id="name" class="hidden-xs hidden-sm">rulerLwx</h2>
          <h3 id="title" class="hidden-xs hidden-sm hidden-md">thinking...</h3>
          <small id="location" class="text-muted hidden-xs hidden-sm"><i class="icon icon-map-marker"></i>Guangzhou, China</small>
        </div><div class="search" id="search-form-wrap">
    <form class="search-form sidebar-form">
        <div class="input-group">
            <input type="text" class="search-form-input form-control" placeholder="Search" />
            <span class="input-group-btn">
                <button type="submit" class="search-form-submit btn btn-flat" onclick="return false;"><i
                        class="icon icon-search"></i></button>
            </span>
        </div>
        <div class="ins-search">
            <div class="ins-search-mask"></div>
            <div class="ins-search-container">
                <div class="ins-input-wrapper">
                    <input type="text" class="ins-search-input" placeholder="Type something..."
                        x-webkit-speech />
                    <button type="button" class="close ins-close ins-selectable" data-dismiss="modal"
                        aria-label="Close"><span aria-hidden="true">×</span></button>
                </div>
                <div class="ins-section-wrapper">
                    <div class="ins-section-container"></div>
                </div>
            </div>
        </div>
    </form>
</div>
        <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#main-navbar" aria-controls="main-navbar" aria-expanded="false">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
      </div>
      <nav id="main-navbar" class="collapse navbar-collapse" itemscope itemtype="http://schema.org/SiteNavigationElement" role="navigation">
        <ul class="nav navbar-nav main-nav">
            <li class="menu-item menu-item-home">
                <a href="/">
                    <i class="icon icon-home-fill"></i>
                  <span class="menu-title">Home</span>
                </a>
            </li>
            <li class="menu-item menu-item-archives">
                <a href="/posts/">
                    <i class="icon icon-archives-fill"></i>
                  <span class="menu-title">Archives</span>
                </a>
            </li>
            <li class="menu-item menu-item-categories">
                <a href="/categories/">
                    <i class="icon icon-folder"></i>
                  <span class="menu-title">Categories</span>
                </a>
            </li>
            <li class="menu-item menu-item-tags">
                <a href="/tags/">
                    <i class="icon icon-tags"></i>
                  <span class="menu-title">Tags</span>
                </a>
            </li>
            <li class="menu-item menu-item-about">
                <a href="/about/">
                    <i class="icon icon-cup-fill"></i>
                  <span class="menu-title">About</span>
                </a>
            </li>
        </ul>
      </nav>
    </div>
  </header>

<aside class="sidebar" itemscope itemtype="http://schema.org/WPSideBar">
  <div class="slimContent">
    
      <div class="widget">
    <h3 class="widget-title">Board</h3>
    <div class="widget-body">
        <div id="board">
            <div class="content">enjoy~
            </div>
        </div>
    </div>
</div>

      <div class="widget">
    <h3 class="widget-title"> Categories</h3>
    <div class="widget-body">
        <ul class="category-list">
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/java-framework/" class="category-list-link">java-framework</a><span class="category-list-count">38</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/java-front-end/" class="category-list-link">java-front-end</a><span class="category-list-count">11</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/java-se/" class="category-list-link">java-se</a><span class="category-list-count">21</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/java-senior/" class="category-list-link">java-senior</a><span class="category-list-count">4</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/linux/" class="category-list-link">linux</a><span class="category-list-count">13</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/tools/" class="category-list-link">tools</a><span class="category-list-count">1</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/%E6%8A%80%E6%9C%AF%E6%9D%82%E7%83%A9/" class="category-list-link">技术杂烩</a><span class="category-list-count">4</span></li>
            <li class="category-list-item"><a href="https://rulerLwx.gitee.io/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/" class="category-list-link">数据库</a><span class="category-list-count">15</span></li>
        </ul>
    </div>
</div>
      <div class="widget">
    <h3 class="widget-title"> Tags</h3>
    <div class="widget-body">
        <ul class="tag-list">
            
            
            <li class="tag-list-item"><a href="https://rulerLwx.gitee.io/tags/jvm/" class="tag-list-link">jvm</a><span
                    class="tag-list-count">1</span></li>
            
            
            <li class="tag-list-item"><a href="https://rulerLwx.gitee.io/tags/%E5%A4%9A%E7%BA%BF%E7%A8%8B/" class="tag-list-link">多线程</a><span
                    class="tag-list-count">2</span></li>
            
            
            <li class="tag-list-item"><a href="https://rulerLwx.gitee.io/tags/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/" class="tag-list-link">网络编程</a><span
                    class="tag-list-count">3</span></li>
            
        </ul>

    </div>
</div>
      
<div class="widget">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget-body">
        <ul class="recent-post-list list-unstyled no-thumbnail">
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/%E8%87%AA%E5%B7%B1%E5%8A%A8%E6%89%8B%E4%B8%80%E6%89%B9%E9%87%8F%E7%A7%BB%E5%8A%A8%E9%87%8D%E5%91%BD%E5%90%8D%E6%96%87%E4%BB%B6/" class="title">自己动手（一）——批量移动、重命名文件</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-27 17:50:02 &#43;0800 CST" itemprop="datePublished">2020-07-27</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/%E5%85%B3%E4%BA%8Einteger%E7%9A%84-128~127%E7%BC%93%E5%AD%98/" class="title">关于Integer的 -128~127缓存</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-11 16:56:21 &#43;0800 CST" itemprop="datePublished">2020-07-11</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/%E8%B7%A8%E5%9F%9F%E9%97%AE%E9%A2%98/" class="title">跨域问题</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-08 22:41:12 &#43;0800 CST" itemprop="datePublished">2020-07-08</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/" class="title">个人博客搭建</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-05 18:58:47 &#43;0800 CST" itemprop="datePublished">2020-07-05</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://rulerLwx.gitee.io/2020/07/centos/" class="title">CentOS-</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-07-01 18:58:47 &#43;0800 CST" itemprop="datePublished">2020-07-01</time>
                    </p>
                </div>
            </li>
        </ul>
    </div>
</div>
  </div>
</aside>

    
    
<aside class="sidebar sidebar-toc collapse" id="collapseToc" itemscope itemtype="http://schema.org/WPSideBar">
  <div class="slimContent">
    <h4 class="toc-title">Catalogue</h4>
    <nav id="toc" class="js-toc toc">

    </nav>
  </div>
</aside>
<main class="main" role="main"><div class="content">
  <article id="-" class="article article-type-" itemscope
    itemtype="http://schema.org/BlogPosting">
    
    <div class="article-header">
      <h1 itemprop="name">
  <a
    class="article-title"
    href="/2020/07/java-framework-rabbitmq-1/"
    >Java-framework-RabbitMQ-1</a
  >
</h1>

      <div class="article-meta">
        
<span class="article-date">
  <i class="icon icon-calendar-check"></i>&nbsp;
<a href="https://rulerLwx.gitee.io/2020/07/java-framework-rabbitmq-1/" class="article-date">
  <time datetime="2020-07-01 18:58:47 &#43;0800 CST" itemprop="datePublished">2020-07-01</time>
</a>
</span>
<span class="article-category">
  <i class="icon icon-folder"></i>&nbsp;
  <a class="article-category-link" href="/categories/java-framework/"> Java-framework </a>
</span>

        <span class="post-comment"><i class="icon icon-comment"></i>&nbsp;<a href="/2020/07/java-framework-rabbitmq-1/#comments"
            class="article-comment-link">Comments</a></span>
		<span class="post-wordcount hidden-xs" itemprop="wordCount">Word Count: 4576words</span>
		<span class="post-readcount hidden-xs" itemprop="timeRequired">Read Count: 10minutes </span>
      </div>
    </div>
    <div class="article-entry marked-body js-toc-content" itemprop="articleBody">
      <h1 id="安装rabbitmq一">安装RabbitMQ（一）</h1>
<h2 id="1安装erlang">1、安装Erlang</h2>
<p>RabbitMQ需要Erlang环境，Erlang([&lsquo;ə:læŋ])是一种通用的面向并发的编程语言，它由瑞典电信设备制造商爱立信所辖的
CS-Lab 开发，目的是创造一种可以应对大规模并发活动的编程语言和运行环境</p>
<pre><code class="language-sh">cd /usr/local/src/
mkdir rabbitmq
cd rabbitmq

wget https://packages.erlang-solutions.com/erlang-solutions-1.0-1.noarch.rpm
rpm -Uvh erlang-solutions-1.0-1.noarch.rpm

rpm --import http://packages.erlang-solutions.com/rpm/erlang_solutions.asc

yum install erlang

erl -version # 查看是否安装成功
</code></pre>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708082012.png" alt=""></p>
<h2 id="2安装rabbitmq-server">2、安装RabbitMQ Server</h2>
<p>安装环境：CentOS7、RabbitMQ－Server：3.7.15</p>
<pre><code class="language-sh">cd /usr/local/src/rabbitmq
# wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.5.1/rabbitmq-server-3.5.1-1.noarch.rpm
wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.7.15/rabbitmq-server-3.7.15-1.el7.noarch.rpm
# rpm --import http://www.rabbitmq.com/rabbitmq-signing-key-public.asc
rpm --import https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc
yum install rabbitmq-server-3.7.15-1.el7.noarch.rpm
</code></pre>
<p>rqbbitmq跟centos版本有关系</p>
<p>参考了：https://www.rabbitmq.com/install-rpm.html#downloads</p>
<h2 id="3启动rabbitmq">3、启动RabbitMQ</h2>
<pre><code class="language-sh">1.配置为守护进程随系统自动启动，root权限下执行:
	chkconfig rabbitmq-server on
2.启动rabbitMQ服务
	/sbin/service rabbitmq-server start
</code></pre>
<p>可能遇到启动失败，</p>
<p>参考：https://stackoverflow.com/questions/25816918/not-able-to-start-rabbitmq-server-in-centos-7-using-systemctL</p>
<p>mq版本问题：https://ask.csdn.net/questions/694983</p>
<h2 id="4安装web管理界面插件">4、安装Web管理界面插件</h2>
<pre><code class="language-sh">1.安装命令
	rabbitmq-plugins enable rabbitmq_management
2.安装成功后会显示如下内容
	The following plugins have been enabled:
	  mochiweb
	  webmachine
	  rabbitmq_web_dispatch
	  amqp_client
	  rabbitmq_management_agent
	  rabbitmq_management
	Plugin configuration has changed. Restart RabbitMQ for changes to take effect.
</code></pre>
<h2 id="5设置rabbitmq远程ip登录">5、设置RabbitMQ远程ip登录</h2>
<p>这里我们以创建个oldlu帐号，密码123456为例，创建一个账号并支持远程ip访问。</p>
<pre><code>1.创建账号
	rabbitmqctl add_user oldlu 123456
2.设置用户角色
	rabbitmqctl  set_user_tags  oldlu  administrator
3.设置用户权限
	rabbitmqctl set_permissions -p &quot;/&quot; oldlu &quot;.*&quot; &quot;.*&quot; &quot;.*&quot;
4.设置完成后可以查看当前用户和角色(需要开启服务)
	rabbitmqctl list_users
</code></pre>
<p>浏览器输入：serverip:15672。其中serverip是RabbitMQ-Server所在主机的ip。</p>
<h1 id="安装-rabbitmq二docker">安装 RabbitMQ（二）：docker</h1>
<p>参考《Linux-Docker-1》</p>
<h1 id="rabbitmq-界面操作">RabbitMQ 界面操作</h1>
<h2 id="添加用户">添加用户</h2>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708082758.png" alt=""></p>
<h2 id="virtual-hosts">virtual hosts</h2>
<p>virtual hosts 相当于 mysql 的 db ，权限操作。</p>
<p>每个VirtualHost相当于一个相对独立的 RabbitMQ 服务器，每个VirtualHost之间是相互隔离的。exchange、queue、message不能互通。</p>
<p>名称一般以 / 开头</p>
<p>1）创建</p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708082854.png" alt=""></p>
<p>2）授权给用户</p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708082917.png" alt=""></p>
<h1 id="为什么用mq">为什么用MQ？</h1>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708082945.png" alt=""></p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708083017.png" alt=""></p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708083111.png" alt=""></p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708083132.png" alt=""></p>
<h1 id="消息队列基础">消息队列基础</h1>
<h1 id="入门示例">入门示例</h1>
<p>官方示例：https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-amqp</p>
<p>1）创建springboot项目</p>
<p>2）依赖</p>
<pre><code class="language-xml">	&lt;dependency&gt;
		&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
		&lt;artifactId&gt;spring-boot-starter-amqp&lt;/artifactId&gt;
	&lt;/dependency&gt;
</code></pre>
<p>3）application.properties</p>
<pre><code class="language-properties">spring.application.name=spring-cloud-mq

spring.rabbitmq.host=192.168.12.132
spring.rabbitmq.port=5672
spring.rabbitmq.username=oldlu
spring.rabbitmq.password=123456
</code></pre>
<p>4）启动类</p>
<pre><code class="language-java">@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}
</code></pre>
<p>5）队列、发送者、接收者</p>
<pre><code class="language-java">package com.demo;

import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 创建消息队列
 *
 * Created by lwx on 2019/6/16.
 */
@Configuration
public class QueueConfig {
    //注意：Queue是 org.springframework.amqp.core.Queue;
    @Bean
    public Queue createQueue(){

        return new Queue(&quot;hello-queue&quot;);
    }
}

</code></pre>
<pre><code class="language-java">@Component
public class Sender {

    @Autowired
    private AmqpTemplate rabbitAmqpTemplate;

    public void send(String msg) {
        /**
         * 参数一：消息队列名称
         * 参数二：消息
         */
        this.rabbitAmqpTemplate.convertAndSend(&quot;hello-queue&quot;,msg);
    }
}
</code></pre>
<pre><code>@Component
public class Receiver {

    /**
     * 接收消息，采用消息队列监听机制
     */
    @RabbitListener(queues = {&quot;hello-queue&quot;})
    public void process(String msg){
        System.out.println(&quot;receiver:&quot;+msg);
    }
}
</code></pre>
<p>6）测试</p>
<pre><code class="language-java">@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)
public class QueueTest {

    @Autowired
    private Sender sender;

    @Test
    public void test1(){
        this.sender.send(&quot;hello rabbitmq&quot;);
    }
}
</code></pre>
<p>注：这只是一个简单示例，其实没什么用</p>
<h1 id="rabbitmq原理图">RabbitMQ原理图</h1>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708083236.png" alt=""></p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708083250.png" alt=""></p>
<ol>
<li>Message
消息。消息是不具名的，它由消息头、消息体组成。消息体是不透明的，而消息头则由
一系列可选属性组成，这些属性包括：routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出消息可能持久性存储)等。</li>
<li>Publisher
消息的生产者。也是一个向交换器发布消息的客户端应用程序。</li>
<li>Consumer
消息的消费者。表示一个从消息队列中取得消息的客户端应用程序。</li>
<li>Exchange
交换器。用来接收生产者发送的消息并将这些消息路由给服务器中的队列。
三种常用的交换器类型
<ol>
<li>direct(发布与订阅完全匹配)</li>
<li>fanout(广播)</li>
<li>topic(主题，规则匹配)</li>
</ol>
</li>
<li>Binding
绑定。用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息
队列连接起来的路由规则，所以可以将交换器理解成一个由绑定构成的路由表。</li>
<li>Queue
消息队列。用来保存消息直到发送给消费者。它是消息的容器，也是消息的终点。一
个消息可投入一个或多个队列。消息一直在队列里面，等待消费者链接到这个队列将其取
走。</li>
<li>Routing-key
路由键。RabbitMQ 决定消息该投递到哪个队列的规则。
队列通过路由键绑定到交换器。
消息发送到MQ 服务器时，消息将拥有一个路由键，即便是空的，RabbitMQ 也会将其
和绑定使用的路由键进行匹配。
如果相匹配，消息将会投递到该队列。
如果不匹配，消息将会进入黑洞。</li>
<li>Connection
链接。指rabbit 服务器和服务建立的TCP 链接。</li>
<li>Channel 信道。
<ol>
<li>Channel 中文叫做信道，是TCP 里面的虚拟链接。例如：电缆相当于TCP，信道是
一个独立光纤束，一条TCP 连接上创建多条信道是没有问题的。</li>
<li>TCP 一旦打开，就会创建AMQP 信道。</li>
<li>无论是发布消息、接收消息、订阅队列，这些动作都是通过信道完成的。</li>
</ol>
</li>
<li>Virtual Host
虚拟主机。表示一批交换器，消息队列和相关对象。虚拟主机是共享相同的身份认证
和加密环境的独立服务器域。每个vhost 本质上就是一个mini 版的RabbitMQ 服务器，拥有
自己的队列、交换器、绑定和权限机制。vhost 是AMQP 概念的基础，必须在链接时指定，
RabbitMQ 默认的vhost 是/</li>
<li>Borker
表示消息队列服务器实体。</li>
</ol>
<p>交换器和队列的关系：</p>
<p>交换器是通过路由键和队列绑定在一起的，如果消息拥有的路由键跟队列和交换器的
路由键匹配，那么消息就会被路由到该绑定的队列中。
也就是说，消息到队列的过程中，消息首先会经过交换器，接下来交换器在通过路由
键匹配分发消息到具体的队列中。
路由键可以理解为匹配的规则。</p>
<p>RabbitMQ 为什么需要信道？为什么不是TCP 直接通信？</p>
<ol>
<li>TCP 的创建和销毁开销特别大。创建需要3 次握手，销毁需要4 次分手。</li>
<li>如果不用信道，那应用程序就会以TCP 链接Rabbit，高峰时每秒成千上万条链接
会造成资源巨大的浪费，而且操作系统每秒处理TCP 链接数也是有限制的，必定造成性能
瓶颈。</li>
<li>信道的原理是一条线程一条通道，多条线程多条通道同用一条TCP 链接。一条TCP
链接可以容纳无限的信道，即使每秒成千上万的请求也不会成为性能的瓶颈。</li>
</ol>
<h1 id="rabbitmq交换器讲解">RabbitMQ交换器讲解</h1>
<p>三种常用的交换器类型</p>
<ul>
<li>direct(发布与订阅完全匹配)</li>
<li>topic(主题，规则匹配)</li>
<li>fanout(广播)</li>
</ul>
<h2 id="direct交换器">Direct交换器</h2>
<h3 id="需求">需求</h3>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708083327.png" alt=""></p>
<h3 id="代码实现">代码实现</h3>
<p>1）创建两个工程，生产者、消费者</p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708083406.png" alt=""></p>
<p>2）修改全局配置文件</p>
<p>消费者（Consumer）</p>
<pre><code>spring.application.name=spring-cloud-mq

spring.rabbitmq.host=192.168.12.132
spring.rabbitmq.port=5672
spring.rabbitmq.username=oldlu
spring.rabbitmq.password=123456

#自定义交换器名称
mq.config.exchange=log.direct

#自定义info队列名称、路由键
mq.config.queue.info=log.info
mq.config.queue.info.routing.key=log.info.routing.key

#自定义error队列名称、路由键
mq.config.queue.error=log.error
mq.config.queue.error.routing.key=log.error.routing.key
</code></pre>
<p>生产者（Provider）</p>
<pre><code>spring.application.name=spring-cloud-mq

spring.rabbitmq.host=192.168.12.132
spring.rabbitmq.port=5672
spring.rabbitmq.username=oldlu
spring.rabbitmq.password=123456

#自定义交换器名称
mq.config.exchange=log.direct

#自定义info/error路由键
mq.config.queue.info.routing.key=log.info.routing.key
mq.config.queue.error.routing.key=log.error.routing.key
</code></pre>
<p>3）Consumer下的两个消费器</p>
<pre><code class="language-java">/**
 * 接收info级别的消息处理器
 *
 * Created by lwx on 2019/6/16.
 */
@Component
@RabbitListener(
        bindings =@QueueBinding(
                value = @Queue(value = &quot;${mq.config.queue.info}&quot;,autoDelete =&quot;true&quot;),//配置队列名称、是否是一个可删除的临时队列
                exchange = @Exchange(value = &quot;${mq.config.exchange}&quot;,type = ExchangeTypes.DIRECT),//配置交换器名称、指定交换器类型
                key = &quot;${mq.config.queue.info.routing.key}&quot;
        )
)
public class InfoReceiver {

    @RabbitHandler
    public void process(String msg){
        System.out.println(&quot;info.........receiver:&quot;+msg);
    }
}
</code></pre>
<pre><code class="language-java">/**
 * 接收error级别的消息处理器
 *
 * Created by lwx on 2019/6/16.
 */
@Component
@RabbitListener(
        bindings =@QueueBinding(
                value = @Queue(value = &quot;${mq.config.queue.error}&quot;,autoDelete =&quot;true&quot;),//配置队列名称、是否是一个可删除的临时队列
                exchange = @Exchange(value = &quot;${mq.config.exchange}&quot;,type = ExchangeTypes.DIRECT),//配置交换器名称、指定交换器类型
                key = &quot;${mq.config.queue.error.routing.key}&quot;
        )
)
public class ErrorReceiver {

    @RabbitHandler
    public void process(String msg){
        System.out.println(&quot;error.......receiver:&quot;+msg);
    }
}
</code></pre>
<p>4）Provider生产者</p>
<pre><code class="language-java">/**
 * 消息发送者
 *
 * Created by lwx on 2019/6/16.
 */
@Component
public class Sender {

    @Autowired
    private AmqpTemplate rabbitAmqpTemplate;

    @Value(&quot;${mq.config.exchange}&quot;)
    private String exchange;

    @Value(&quot;${mq.config.queue.info.routing.key}&quot;)
    private String routingkey;

    public void send(String msg) {
        /**
         * 参数一：交换器名称
         * 参数二：路由键
         * 参数三：消息
         */
        this.rabbitAmqpTemplate.convertAndSend(this.exchange,this.routingkey,msg);
    }
}
</code></pre>
<p>5）测试</p>
<p>步骤一：启动消费者项目的引导类</p>
<p>步骤二：运行生产者的测试代码</p>
<pre><code class="language-java">@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)
public class QueueTest {

    @Autowired
    private Sender sender;

    @Test
    public void test1() throws InterruptedException {
        while (true) {
            Thread.sleep(1000);
            this.sender.send(&quot;hello rabbitmq&quot;);
        }
    }
}
</code></pre>
<p>在消费者项目的控制台上看到输出：</p>
<pre><code>info.........receiver:hello rabbitmq
...
</code></pre>
<h2 id="topic交换器">Topic交换器</h2>
<h3 id="需求-1">需求</h3>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708083440.png" alt=""></p>
<h3 id="代码实现-1">代码实现</h3>
<p>创建两个项目</p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708083501.png" alt=""></p>
<p>1）全局配置文件</p>
<p>consumer</p>
<pre><code>spring.application.name=spring-cloud-mq

spring.rabbitmq.host=192.168.12.132
spring.rabbitmq.port=5672
spring.rabbitmq.username=oldlu
spring.rabbitmq.password=123456

#自定义交换器名称
mq.config.exchange=log.topic

#自定义info队列名称
mq.config.queue.info=log.info

#自定义error队列名称
mq.config.queue.error=log.error

#自定义log队列名称
mq.config.queue.logs=log.all
</code></pre>
<p>provider</p>
<pre><code>spring.application.name=spring-cloud-mq

spring.rabbitmq.host=192.168.12.132
spring.rabbitmq.port=5672
spring.rabbitmq.username=oldlu
spring.rabbitmq.password=123456

#自定义交换器名称
mq.config.exchange=log.topic
</code></pre>
<p>2）编写provider</p>
<pre><code class="language-java">/**
 * 消息发送者
 *
 * 用户服务
 *
 * Created by lwx on 2019/6/16.
 */
@Component
public class UserSender {

    @Autowired
    private AmqpTemplate rabbitAmqpTemplate;

    @Value(&quot;${mq.config.exchange}&quot;)
    private String exchange;

    public void send(String msg) {
        /**
         * 参数一：交换器名称
         * 参数二：路由键
         * 参数三：消息
         */
        this.rabbitAmqpTemplate.convertAndSend(this.exchange,&quot;user.log.debug&quot;,&quot;user.log.debug....&quot;+msg);
        this.rabbitAmqpTemplate.convertAndSend(this.exchange,&quot;user.log.info&quot;,&quot;user.log.info....&quot;+msg);
        this.rabbitAmqpTemplate.convertAndSend(this.exchange,&quot;user.log.warn&quot;,&quot;user.log.warn....&quot;+msg);
        this.rabbitAmqpTemplate.convertAndSend(this.exchange,&quot;user.log.error&quot;,&quot;user.log.error....&quot;+msg);
    }
}
</code></pre>
<pre><code class="language-java">/**
 * 消息发送者
 *
 * 商品服务
 *
 * Created by lwx on 2019/6/16.
 */
@Component
public class ProductSender {

    @Autowired
    private AmqpTemplate rabbitAmqpTemplate;

    @Value(&quot;${mq.config.exchange}&quot;)
    private String exchange;

    public void send(String msg) {
        /**
         * 参数一：交换器名称
         * 参数二：路由键
         * 参数三：消息
         */
        this.rabbitAmqpTemplate.convertAndSend(this.exchange,&quot;product.log.debug&quot;,&quot;product.log.debug....&quot;+msg);
        this.rabbitAmqpTemplate.convertAndSend(this.exchange,&quot;product.log.info&quot;,&quot;product.log.info....&quot;+msg);
        this.rabbitAmqpTemplate.convertAndSend(this.exchange,&quot;product.log.warn&quot;,&quot;product.log.warn....&quot;+msg);
        this.rabbitAmqpTemplate.convertAndSend(this.exchange,&quot;product.log.error&quot;,&quot;product.log.error....&quot;+msg);
    }
}
</code></pre>
<pre><code class="language-java">/**
 * 消息发送者
 *
 * 订单服务
 *
 * Created by lwx on 2019/6/16.
 */
@Component
public class OrderSender {

    @Autowired
    private AmqpTemplate rabbitAmqpTemplate;

    @Value(&quot;${mq.config.exchange}&quot;)
    private String exchange;

    public void send(String msg) {
        /**
         * 参数一：交换器名称
         * 参数二：路由键
         * 参数三：消息
         */
        this.rabbitAmqpTemplate.convertAndSend(this.exchange,&quot;order.log.debug&quot;,&quot;order.log.debug....&quot;+msg);
        this.rabbitAmqpTemplate.convertAndSend(this.exchange,&quot;order.log.info&quot;,&quot;order.log.info....&quot;+msg);
        this.rabbitAmqpTemplate.convertAndSend(this.exchange,&quot;order.log.warn&quot;,&quot;order.log.warn....&quot;+msg);
        this.rabbitAmqpTemplate.convertAndSend(this.exchange,&quot;order.log.error&quot;,&quot;user.log.error....&quot;+msg);
    }
}
</code></pre>
<p>3）编写consumer</p>
<pre><code class="language-java">/**
 * 接收info级别的消息处理器
 *
 * Created by lwx on 2019/6/16.
 */
@Component
@RabbitListener(
        bindings =@QueueBinding(
                value = @Queue(value = &quot;${mq.config.queue.info}&quot;,autoDelete =&quot;true&quot;),//配置队列名称、是否是一个可删除的临时队列
                exchange = @Exchange(value = &quot;${mq.config.exchange}&quot;,type = ExchangeTypes.TOPIC),//配置交换器名称、指定交换器类型
                key = &quot;*.log.info&quot;
        )
)
public class InfoReceiver {

    @RabbitHandler
    public void process(String msg){
        System.out.println(&quot;info.........receiver:&quot;+msg);
    }
}
</code></pre>
<pre><code class="language-java">/**
 * 接收error级别的消息处理器
 *
 * Created by lwx on 2019/6/16.
 */
@Component
@RabbitListener(
        bindings =@QueueBinding(
                value = @Queue(value = &quot;${mq.config.queue.error}&quot;,autoDelete =&quot;true&quot;),//配置队列名称、是否是一个可删除的临时队列
                exchange = @Exchange(value = &quot;${mq.config.exchange}&quot;,type = ExchangeTypes.TOPIC),//配置交换器名称、指定交换器类型
                key = &quot;*.log.error&quot;
        )
)
public class ErrorReceiver {

    @RabbitHandler
    public void process(String msg){
        System.out.println(&quot;error.......receiver:&quot;+msg);
    }
}
</code></pre>
<pre><code class="language-java">/**
 * 接收所有日志级别的消息处理器
 *
 * Created by lwx on 2019/6/16.
 */
@Component
@RabbitListener(
        bindings =@QueueBinding(
                value = @Queue(value = &quot;${mq.config.queue.logs}&quot;,autoDelete =&quot;true&quot;),//配置队列名称、是否是一个可删除的临时队列
                exchange = @Exchange(value = &quot;${mq.config.exchange}&quot;,type = ExchangeTypes.TOPIC),//配置交换器名称、指定交换器类型
                key = &quot;*.log.*&quot;
        )
)
public class LogsReceiver {

    @RabbitHandler
    public void process(String msg){
        System.out.println(&quot;all.........receiver:&quot;+msg);
    }
}
</code></pre>
<p>4）测试</p>
<p>步骤一：运行consumer引导类</p>
<p>步骤二：运行provider测试方法</p>
<pre><code class="language-java">@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)
public class QueueTest {

    @Autowired
    private UserSender userSender;

    @Autowired
    private ProductSender productSender;

    @Autowired
    private OrderSender orderSender;

    @Test
    public void test1() throws InterruptedException {
        this.userSender.send(&quot;userSender...........hello rabbitmq&quot;);
        this.productSender.send(&quot;productSender...........hello rabbitmq&quot;);
        this.orderSender.send(&quot;orderSender...........hello rabbitmq&quot;);
    }
}
</code></pre>
<h2 id="fanout交换器">Fanout交换器</h2>
<h3 id="需求-2">需求</h3>
<p>原来耦全方式：
<img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708083540.png" alt=""></p>
<p>使用mq后：
<img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708083559.png" alt=""></p>
<h3 id="代码实现-2">代码实现</h3>
<p>1）创建两个项目</p>
<p><img src="https://gitee.com/rulerLwx/PicGo/raw/master/img/20200708083617.png" alt=""></p>
<p>2）修改全局配置文件</p>
<p>consumer</p>
<pre><code>spring.application.name=spring-cloud-mq

spring.rabbitmq.host=192.168.12.132
spring.rabbitmq.port=5672
spring.rabbitmq.username=oldlu
spring.rabbitmq.password=123456

#自定义交换器名称
mq.config.exchange=order.fanout

#自定义队列名称
mq.config.queue.sms=order.sms
mq.config.queue.push=order.push
</code></pre>
<p>provider</p>
<pre><code>spring.application.name=spring-cloud-mq

spring.rabbitmq.host=192.168.12.132
spring.rabbitmq.port=5672
spring.rabbitmq.username=oldlu
spring.rabbitmq.password=123456

#自定义交换器名称
mq.config.exchange=order.fanout
</code></pre>
<p>广播模式，所有的队列都会接收到消息，所有不需要路由键</p>
<p>3）编写consumer，两个消息处理器</p>
<pre><code class="language-java">/**
 * sms消息处理器
 *
 * @QueueBinding
 *      value 绑定队列名称
 *      exchange 路由器
 *      key 路由键
 *
 * FANOUT模式不需要路由键
 *
 * Created by lwx on 2019/6/16.
 */
@Component
@RabbitListener(
        bindings =@QueueBinding(
                value = @Queue(value = &quot;${mq.config.queue.sms}&quot;,autoDelete =&quot;true&quot;),//配置队列名称、是否是一个可删除的临时队列
                exchange = @Exchange(value = &quot;${mq.config.exchange}&quot;,type = ExchangeTypes.FANOUT)//配置交换器名称、指定交换器类型
        )
)
public class SmsReceiver {

    @RabbitHandler
    public void process(String msg){
        System.out.println(&quot;sms.........receiver:&quot;+msg);
    }
}
</code></pre>
<pre><code class="language-java">/**
 * push消息处理器
 *
 * Created by lwx on 2019/6/16.
 */
@Component
@RabbitListener(
        bindings =@QueueBinding(
                value = @Queue(value = &quot;${mq.config.queue.push}&quot;,autoDelete =&quot;true&quot;),//配置队列名称、是否是一个可删除的临时队列
                exchange = @Exchange(value = &quot;${mq.config.exchange}&quot;,type = ExchangeTypes.FANOUT)//配置交换器名称、指定交换器类型
        )
)
public class PushReceiver {

    @RabbitHandler
    public void process(String msg){
        System.out.println(&quot;push.......receiver:&quot;+msg);
    }
}
</code></pre>
<p>4）编写provider</p>
<pre><code>@Component
public class Sender {

    @Autowired
    private AmqpTemplate rabbitAmqpTemplate;

    @Value(&quot;${mq.config.exchange}&quot;)
    private String exchange;

    public void send(String msg) {
        /**
         * 参数一：交换器名称
         * 参数二：路由键
         * 参数三：消息
         *
         * fanout模式，参数二传&quot;&quot;
         */
        this.rabbitAmqpTemplate.convertAndSend(this.exchange,&quot;&quot;,msg);
    }
}
</code></pre>
<p>注意：fanout模式时，参数二传&rdquo;&rdquo;</p>
<p>5）测试</p>
<p>步骤一：启动consumer引导类</p>
<p>步骤二：启动provider测试类</p>
<pre><code class="language-java">@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)
public class QueueTest {

    @Autowired
    private Sender sender;

    @Test
    public void test1(){
        this.sender.send(&quot;hello rabbitmq&quot;);
    }
}
</code></pre>

    </div>
    <div class="article-footer">
<blockquote class="mt-2x">
  <ul class="post-copyright list-unstyled">
    <li class="post-copyright-link hidden-xs">
      <strong>Permalink: </strong>
      <a href="https://rulerLwx.gitee.io/2020/07/java-framework-rabbitmq-1/" title="Java-framework-RabbitMQ-1" target="_blank" rel="external">https://rulerLwx.gitee.io/2020/07/java-framework-rabbitmq-1/</a>
    </li>
    <li class="post-copyright-license">
      <strong>License：</strong><a href="http://creativecommons.org/licenses/by/4.0/deed.zh" target="_blank" rel="external">CC BY 4.0 CN</a>
    </li>
  </ul>
</blockquote>

<div class="panel panel-default panel-badger">
  <div class="panel-body">
    <figure class="media">
      <div class="media-left">
        <a href="https://gitee.com/rulerLwx" target="_blank" class="img-burn thumb-sm visible-lg">
          <img src="https://rulerLwx.gitee.io/avatar.png" class="img-rounded w-full" alt="">
        </a>
      </div>
      <div class="media-body">
        <h3 class="media-heading"><a href="https://gitee.com/rulerLwx" target="_blank"><span class="text-dark">rulerLwx</span><small class="ml-1x">thinking...</small></a></h3>
        <div>Good Good Study, Day Day Up~</div>
      </div>
    </figure>
  </div>
</div>
    </div>
  </article>
<section id="comments">
    <div id="vcomments"></div>
</section>

</div><nav class="bar bar-footer clearfix" data-stick-bottom>
    <div class="bar-inner">
        <ul class="pager pull-left">
            <li class="prev">
                <a href="https://rulerLwx.gitee.io/2020/07/java-framework-rabbitmq-2/" title="Java-framework-RabbitMQ-2"><i
                        class="icon icon-angle-left"
                        aria-hidden="true"></i><span>&nbsp;&nbsp;Older</span></a>
            </li>
            <li class="next">
                <a href="https://rulerLwx.gitee.io/2020/07/java-framework-mybatis-4/"
                    title="Java-framework-MyBatis-4-整合Spring"><span>Newer&nbsp;&nbsp;</span><i
                        class="icon icon-angle-right" aria-hidden="true"></i></a>
            </li>
            
            <li class="toggle-toc">
                <a class="toggle-btn collapsed" data-toggle="collapse" href="#collapseToc" aria-expanded="false"
                    title="Catalogue" role="button">
                    <span>[&nbsp;</span><span>Catalogue</span>
                    <i class="text-collapsed icon icon-anchor"></i>
                    <i class="text-in icon icon-close"></i>
                    <span>]</span>
                </a>
            </li>
        </ul>
        <div class="bar-right">
            <div class="share-component" data-sites="weibo,qq,wechat"
                data-mobile-sites="weibo,qq,qzone"></div>
        </div>
    </div>
</nav>

</main><footer class="footer" itemscope itemtype="http://schema.org/WPFooter">
<ul class="social-links">
    <li><a href="https://gitee.com/rulerLwx" target="_blank" title="gitee" data-toggle=tooltip data-placement=top >
            <i class="icon icon-gitee"></i></a></li>
    <li><a href="https://github.com/wolf-lea" target="_blank" title="github" data-toggle=tooltip data-placement=top >
            <i class="icon icon-github"></i></a></li>
</ul>
  <div class="copyright">
    &copy;2020  -
    2020
    <div class="publishby">
        Theme by <a href="https://github.com/xiaoheiAh" target="_blank"> xiaoheiAh </a>base on<a href="https://github.com/xiaoheiAh/hugo-theme-pure" target="_blank"> pure</a>.
    </div>
  </div>
</footer>

<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_SVG"></script>
<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
            showMathMenu: false, //disables context menu
            tex2jax: {
            inlineMath: [ ['$','$'], ['\\(','\\)'] ]
           }
    });
</script>


<script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.min.js"></script>
<script>
    window.jQuery || document.write('<script src="js/jquery.min.js"><\/script>')
</script>
<script type="text/javascript" src="https://cdn.staticfile.org/highlight.js/9.15.10/highlight.min.js"></script>
<script type="text/javascript" src="https://cdn.staticfile.org/highlight.js/9.15.10/languages/python.min.js" defer></script>
<script type="text/javascript" src="https://cdn.staticfile.org/highlight.js/9.15.10/languages/javascript.min.js" defer></script><script>
    hljs.configure({
        tabReplace: '    ', 
        classPrefix: ''     
        
    })
    hljs.initHighlightingOnLoad();
</script>
<script src="https://rulerLwx.gitee.io/js/application.min.bdeb64b910570b6c41badc6a05b7afb0c8ad9efd8525de3c7257d59e786326a3.js"></script>
<script src="https://rulerLwx.gitee.io/js/plugin.min.51ff8c7317566f82259170fa36e09c4493adc9b9378b427a01ad3f017ebac7dd.js"></script>

<script>
    (function (window) {
        var INSIGHT_CONFIG = {
            TRANSLATION: {
                POSTS: 'Posts',
                PAGES: 'Pages',
                CATEGORIES: 'Categories',
                TAGS: 'Tags',
                UNTITLED: '(Untitled)',
            },
            ROOT_URL: 'https:\/\/rulerLwx.gitee.io',
            CONTENT_URL: 'https:\/\/rulerLwx.gitee.io\/searchindex.json ',
        };
        window.INSIGHT_CONFIG = INSIGHT_CONFIG;
    })(window);
</script>
<script type="text/javascript" src="https://rulerLwx.gitee.io/js/insight.min.a343cd9a5a7698336b28ef3a7c16a3a1b1d2d5fb17dc8ed04022bbe08cc5459073a15bdafa3a8a58cdd56080784bdd69fa70b1ae8597565c799c57ed00f0e120.js" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.4.2/tocbot.min.js"></script>
<script>
    tocbot.init({
        
        tocSelector: '.js-toc',
        
        contentSelector: '.js-toc-content',
        
        headingSelector: 'h1, h2, h3',
        
        hasInnerContainers: true,
    });
</script>

<script src="https://cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/valine"></script>
<script type="text/javascript">
    var GUEST = ['nick', 'mail', 'link'];
    var meta = 'nick,mail';
    meta = meta.split(',').filter(function (item) {
        return GUEST.indexOf(item) > -1;
    });
    new Valine({
        el: '#vcomments',
        verify: null ,
        notify: null ,
        appId: 'IyAB0PSPRazTPDxitO1ddQ7O-gzGzoHsz',
        appKey: '5rBJTq4KidYF33eXwvRVhtEH',
        placeholder: 'enjoy~',
        avatar: 'mm',
        meta: meta,
        pageSize: '10' || 10,
        visitor: false 
});
</script>

  </body>
</html>
